<?php

/**
 * @author IvanBozhakov 
 */
use Illuminate\Cache\StoreInterface;

class HappyHour implements \HappyHourInterface
{

    /**
     * Variable for global settings
     * 
     * @static
     * @var array
     */
    private static $config = array();

    /**
     * @var Object|null Keep the current instance caching
     */
    private $cache = null;

    /**
     * @var DateTime|null Current Date
     */
    private $dateNow = null;

    /**
     * Create a new Memcache store.
     * 
     * @param  Illuminate\Cache\StoreInterface  $cache
     * @return void
     */
    function __construct(StoreInterface $cache)
    {
        $this->dateNow = date_format(new DateTime(), 'Y-m-d');
        $this->cache = $cache;

        if (!$this->getHappyHour()) {
            /* Set in store date for 1 day = 1440 minutes */
            $cache->put($this->dateNow, $this->generatedHours(), 1440);
        }
    }

    /**
     * Validate  array date
     * 
     * @param array $config list of elements for validation
     * @throws InvalidArgumentException
     * @static
     */
    private static function validateConfigList(array $config)
    {
        foreach ($config['list'] as $listHour) {
            if (!strtotime($listHour)) {
                throw new InvalidArgumentException("Time element of array is not valid datetime format");
            }
        }

        if (!strtotime($config['dateStart']) || !strtotime($config['dateEnd'])) {
            throw new InvalidArgumentException("Invalid start or end date");
        }

        if (!is_numeric($config['bonus'])) {
            throw new InvalidArgumentException("Bunus must be a number");
        }

        if (!is_numeric($config['duration'])) {
            throw new InvalidArgumentException("Time duration must be a number");
        }
        self::$config = $config;
    }

    /**
     * Set array configuration
     * 
     * @method static void run() 
     * @param array $config
     * @throws Exception
     */
    public static function runSystem(array $config)
    {
        try {
            /* Checking for turn on  system */
            if (strtolower($config['turn']) === 'on') {
                /* Check validation */
                static::validateConfigList($config);
            } else {
                throw new Exception("Check for turn system");
            }
        } catch (Exception $exc) {
            echo $exc->getMessage() . '<br/>' . $exc->getTraceAsString();
            die();
        }
    }

    /**
     * Check for HappyHour at the moment
     * 
     * @return bool
     */
    public function isHappyHour()
    {

        $dateStart = date_format(new DateTime(self::$config['dateStart']), 'Y-m-d H:i:s');
        $dateEnd = date_format(new DateTime(self::$config['dateEnd']), 'Y-m-d H:i:s');
        $timeNow = date_format(new DateTime(), 'H:i:s');

        if ($this->dateNow > $dateStart && $this->dateNow < $dateEnd) {
            foreach ($this->getHappyHour() as $value) {
                /* calculate how long continues Happy Hour */
                $valueEnd = strtotime($value) + self::$config['duration'] * 60;
                $valueEndFormat = date('H:i:s', $valueEnd);
                /* check set hour in data stor */
                if ($timeNow > $value && $timeNow < $valueEndFormat) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Get list of happy hour 
     * 
     * @return array
     * @throws Exception
     */
    public function getHappyHour()
    {
        try {
            return $this->cache->get($this->dateNow);
        } catch (Exception $exc) {
            echo $exc->getMessage() . '<br/>' . $exc->getTraceAsString();
            die();
        }
    }

    /**
     * Retrieves the bonus value of the happy hour
     * 
     * @param int $credits
     * @return int
     */
    public function getBonusCredits($credits = 0)
    {
        if (!is_numeric($credits)) {
            throw new InvalidArgumentException("Param must be a number");
        }

        if (!is_int($credits)) {
            throw new InvalidArgumentException("Parameter must be integer");
        }

        $bonus = self::$config['bonus'];
        $per = $credits * ($bonus / 100);
        return round($credits + $per);
    }

    /**
     * Generate everyday any HappyHour
     * 
     * @return array numbers
     */
    private function generatedHours()
    {

        /* Take half hours random */
        if (count(self::$config['list']) < 2) {
            $num = 2;
        } else {
            $num = ceil(count(self::$config['list']) / 2);
        }
        $randKey = array_rand(self::$config['list'], $num);

        for ($i = 0; $i < $num; $i++) {
            $hour[$i] = self::$config['list'][$randKey[$i]];
        }
        return $hour;
    }

}
